package org.xbdframework.scheduling.quartz.handler;

import org.xbdframework.scheduling.quartz.QuartzTask;
import org.xbdframework.scheduling.quartz.QuartzTaskHandler;
import org.xbdframework.scheduling.quartz.XbdQuartzJobBean;

import org.apache.commons.lang3.StringUtils;

import org.quartz.*;

/**
 * <code>QuartzTaskHandler</code>的默认实现
 *
 * <pre>
 *     java配置：
 *     {@code @Bean}
 *      public DefaultQuartzTaskHandler defaultQuartzTaskHandler() {
 *          DefaultQuartzTaskHandler defaultQuartzTaskHandler = new DefaultQuartzTaskHandler();
 *          defaultQuartzTaskHandler.setScheduler(scheduler);
 *          return defaultQuartzTaskHandler;
 *      }
 *
 *     xml配置：
 *    {@code
 *       <bean id="defaultQuartzTaskHandler" class=
"org.xbdframework.scheduling.quartz.handler.DefaultQuartzTaskHandler">
 *           <property name="scheduler" ref="scheduler"></property>
 *       </bean>
 *    }
 * </pre>
 *
 * @author luas
 * @since 4.3
 */
public class DefaultQuartzTaskHandler extends QuartzTaskHandler {

	private final Class<? extends XbdQuartzJobBean> jobClass;

	public DefaultQuartzTaskHandler(Class<? extends XbdQuartzJobBean> jobClass) {
		this.jobClass = jobClass;
	}

	/**
	 * 动态添加任务
	 */
	public void addTask(QuartzTask quartzTask) throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(this.jobClass)
				.withIdentity(quartzTask.getName(), quartzTask.getGroup())
				.withDescription(quartzTask.getDescription()).storeDurably().build();

		CronScheduleBuilder cronScheduleBuilder = initCronScheduleBuilder(quartzTask);

		TriggerBuilder<CronTrigger> triggerBuilder = TriggerBuilder.newTrigger()
				.withIdentity(TriggerKey
						.triggerKey(quartzTask.getName(), quartzTask.getGroup()))
				.withSchedule(cronScheduleBuilder)
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETCLASS,
						quartzTask.getTargetClass())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETOBJECT,
						quartzTask.getTargetObject())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD,
						StringUtils.isBlank(quartzTask.getTargetMethod())
								? XbdQuartzJobBean.JOBDETAIL_VALUE_TARGETMETHOD
								: quartzTask.getTargetMethod())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD_PARAM,
						quartzTask.getTargetMethodParam());

		if (quartzTask.getStartAt() != null) {
			triggerBuilder.startAt(quartzTask.getStartAt());
		}

		if (quartzTask.isStartNow()) {
			triggerBuilder.startNow();
		}

		if (quartzTask.getEndAt() != null) {
			triggerBuilder.endAt(quartzTask.getEndAt());
		}

		CronTrigger cronTrigger = triggerBuilder.build();

		scheduler.scheduleJob(jobDetail, cronTrigger);
	}

	/**
	 * 批量动态添加任务
	 */
	public void addTask(QuartzTask... quartzTasks) throws SchedulerException {
		if (quartzTasks != null) {
			for (QuartzTask quartzTask : quartzTasks) {
				addTask(quartzTask);
			}
		}
	}

	/**
	 * 动态更新任务
	 */
	public void updateTask(QuartzTask quartzTask) throws SchedulerException {
		CronTrigger cronTrigger = getTrigger(quartzTask.getName(), quartzTask.getGroup());

		CronScheduleBuilder cronScheduleBuilder = initCronScheduleBuilder(quartzTask);

		TriggerBuilder<CronTrigger> triggerBuilder = cronTrigger.getTriggerBuilder()
				.withIdentity(TriggerKey
						.triggerKey(quartzTask.getName(), quartzTask.getGroup()))
				.withSchedule(cronScheduleBuilder)
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETCLASS,
						quartzTask.getTargetClass())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETOBJECT,
						quartzTask.getTargetObject())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD,
						StringUtils.isBlank(quartzTask.getTargetMethod())
								? XbdQuartzJobBean.JOBDETAIL_VALUE_TARGETMETHOD
								: quartzTask.getTargetMethod())
				.usingJobData(XbdQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD_PARAM,
						quartzTask.getTargetMethodParam());

		if (quartzTask.getStartAt() != null) {
			triggerBuilder.startAt(quartzTask.getStartAt());
		}

		if (quartzTask.isStartNow()) {
			triggerBuilder.startNow();
		}

		if (quartzTask.getEndAt() != null) {
			triggerBuilder.endAt(quartzTask.getEndAt());
		}

		cronTrigger = triggerBuilder.build();

		scheduler.rescheduleJob(
				TriggerKey.triggerKey(quartzTask.getName(), quartzTask.getGroup()),
				cronTrigger);
	}

	/**
	 * 批量动态更新任务
	 */
	public void updateTask(QuartzTask... quartzTasks) throws SchedulerException {
		if (quartzTasks != null) {
			for (QuartzTask quartzTask : quartzTasks) {
				updateTask(quartzTask);
			}
		}
	}

	/**
	 * 暂停任务
	 */
	public void pauseTask(QuartzTask quartzTask) throws SchedulerException {
		JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup());
		scheduler.pauseJob(jobKey);
	}

	/**
	 * 批量暂停任务
	 */
	public void pauseTask(QuartzTask... quartzTasks) throws SchedulerException {
		if (quartzTasks != null) {
			for (QuartzTask quartzTask : quartzTasks) {
				pauseTask(quartzTask);
			}
		}
	}

	/**
	 * 暂停所有任务
	 */
	public void pauseTask() throws SchedulerException {
		scheduler.pauseAll();
	}

	/**
	 * 继续任务
	 */
	public void resumeTask(QuartzTask quartzTask) throws SchedulerException {
		JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup());
		scheduler.resumeJob(jobKey);
	}

	/**
	 * 批量继续任务
	 */
	public void resumeTask(QuartzTask... quartzTasks) throws SchedulerException {
		if (quartzTasks != null) {
			for (QuartzTask quartzTask : quartzTasks) {
				resumeTask(quartzTask);
			}
		}
	}

	/**
	 * 删除任务
	 */
	public void deleteTask(QuartzTask quartzTask) throws SchedulerException {
		JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup());
		scheduler.deleteJob(jobKey);
	}

	/**
	 * 批量删除任务
	 */
	public void deleteTask(QuartzTask... quartzTasks) throws SchedulerException {
		if (quartzTasks != null) {
			for (QuartzTask quartzTask : quartzTasks) {
				deleteTask(quartzTask);
			}
		}
	}

}
